package com.example.forum_system.searchEngine.wordList;

import com.example.forum_system.searchEngine.exception.SearchEngineException;
import lombok.extern.slf4j.Slf4j;

/**
 * @BelongsProject: 0.forum_system
 * @BelongsPackage: com.example.forum_system.SE
 * @Author : 游在海里的鱼
 * @CreateTime : 2023-11-26  20:19
 * @Version : 1.0
 * @Description : 词索引链表，是一个顺序表，且元素下标就是文章的id。虽然费空间，但能提高效率。
 *                因为传统顺序表不支持，所以就自定义了此顺序表。
 */
@Slf4j
public class WordIndexList {
    //默认容量
    private static final int CAPACITY_DEFAULT = 10;
    //最小扩容数，一次性最小扩容
    private static final int DILATATION_MIN = 2;
    //最大扩容数，一次性最大扩容数
    private static final int DILATATION_MAX = 100000;

    //一个“词索引”数组
    private WordIndex[] indexList = new WordIndex[CAPACITY_DEFAULT];


    /*------------------------------------普--通--方--法------------------------------------------------------------------
     * @Desc  : 添加词索引到此词下，因为id就是元素下标，所以当下标超过数组长度时就要扩容.(原顺序表不支持此功能）
     * @Param : [pos, location]
     * @Return: boolean
    **/
    public boolean add(int id,int location){
        //1.id超过数组长度就要扩容
        if(id>= indexList.length){
            dilatation();
        }
        //2.此下标下还未创建WordIndex对象时，就要创建一个对象
        if(indexList[id] == null){
            indexList[id] = WordIndex.IndexFactory(id,location);
            return true;
        }
        //3.已有WordIndex对象
        indexList[id].add(location);
        return true;
    }

    /*------------------------------------普--通--方--法------------------------------------------------------------------
     * @Desc  : 获取此词下，此id文章的WordIndex
     * @Param : [pos]
     * @Return: com.example.forum_system.SE.wordList.WordIndex
    **/
    public WordIndex get(int id) throws SearchEngineException {
        //1.索引是否超出
        if(id>=indexList.length || id<0){
            log.error("索引超出数组长度");
            throw new SearchEngineException("IndexOutOfBounds");
        }
        //2.返回WordIndex
        return indexList[id];
    }


   /*------------------------------------普--通--方--法------------------------------------------------------------------
    * @Desc  : 删除此词下，此id文章的WordIndex
    * @Param : [pos]
    * @Return: com.example.forum_system.SE.wordList.WordIndex
   **/
    public WordIndex remove(int id) throws SearchEngineException {
        //1.索引是否超出
        if(id>=indexList.length || id<0){
            log.error("索引超出数组长度");
            throw new SearchEngineException("IndexOutOfBounds");
        }
        //2.删除并返回删除掉的WordIndex
        WordIndex ret = indexList[id];
        indexList[id] = null;
        return ret;
    }

    /*------------------------------------普--通--方--法------------------------------------------------------------------
     * @Desc  : 私有方法，数组扩容
     * @Param : []
     * @Return: void
    **/
    private void dilatation(){
        //1.得到合理的扩容后长度，通常是原来的1.5倍
        int newlen = (int)(1.5*indexList.length);
        //小于最小扩容量时，修正为最小扩容数。这是为了避免无效扩容，如 （int）1*1.5 = 1
        if(newlen <= indexList.length + DILATATION_MIN){
            newlen = indexList.length + DILATATION_MIN;
        }
        //大于最大扩容量，扩容太多了消耗资源
        if(newlen - indexList.length > DILATATION_MAX){
            newlen = indexList.length + DILATATION_MAX;
        }
        //2.复制得到新的数组
        WordIndex[] newArr = new WordIndex[newlen];
        System.arraycopy(indexList,0,newArr,0,indexList.length);
        indexList = newArr;
    }
}
